
#ifndef _TIROS_INTERNAL_H
#define _TIROS_INTERNAL_H


/* Author: Ratish J. Punnoose, 2006
 * This file is part of TiROS, the Tickless Real-Time Operating System.
 * Copyright(c) 2006, 2007: Ratish J. Punnoose.
 * Copyright(c) 2006 Sandia Corporation. Under the terms of Contract
 * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
 * certain rights in this software. 
 * 
 * TiROS is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 or (at your option) any later version.
 *
 * TiROS is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with TiROS; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 *
 * As a special exception, if other files instantiate templates or use macros
 * or inline functions from this file, or you compile this file and link it
 * with other works to produce a work based on this file, this file does not
 * by itself cause the resulting work to be covered by the GNU General Public
 * License. However the source code for this file must still be made available
 * in accordance with section (3) of the GNU General Public License.
 *
 * This exception does not invalidate any other reasons why a work based on
 * this file might be covered by the GNU General Public License.
 *
 */




#include <tiros/tiros.h>


/** Internal OS function that is called by the hal when a compare
 *   timer has been reached.
 *  
 *  This functiion wakes tasks that have timed out.
 * @param t   Pointer to current time. Do not modify
 * @return 0 if no context switch is needed, 1 if a context switch is
 * needed after.
 * 
 */
uint8_t osint_alarm_reached(trtime_t const * t );


/*lint -e{762} suppress warning for duplicate decl of
 * osint_taskswitcher */

/** Switch tasks to run the ready process.
 *
 * This function is implemented internally in tiros.c.  It is used
 * during a  context switch to store the pointer to the context of the
 * current task in the TCB and to obtain the context pointer of the ready task.
 * This function is called from hal_ctxt_switch().
 * 
 * It is valid to call osint_taskswitcher with an ILLEGAL_STACK
 * argument. This may be necessary when the running task has been
 * deleted. \sa osint_running_task_ctxt.
 * @param old_ctxtptr  Pointer to the context of the currently running process.
 * @return   ILLEGAL_STACK or Stackpointer to the new process */
/*@shared@*/ osstkptr_t osint_taskswitcher(/*@shared@*/ osstkptr_t old_ctxtptr);


/** Return the stack of the running task.
 *
 * NOTE: This function may return ILLEGAL_STACK, if the running task
 * has been deleted.  If hal_ctxt_switch() first retrieves the task
 * stack pointer before saving the context, make sure it checks for an
 * ILLEGAL_STACK.  If the current task has been deleted, there is no
 * need to store its context.  osint_task_switcher() can be called and
 * the next ready task's context can be loaded.
 * @return ILLEGAL_STACK or The context pointer of the running task. */
/*@shared@*/ osstkptr_t  osint_running_task_ctxt(void);





/**  The Task Control Block. Each task has an associated TCB. */
struct TCB {
	/*@shared@*/
	osstkptr_t ctxt_ptr; /**< Stack pointer for the task */

	tid_t priority;		/**< Default priority */
	tid_t eff_priority;	/**< Effective priority */

	uint8_t flags;		/**< Other flags and options.*/
	uint8_t num_mutexes;	/**< Number of mutexes held. */

	trtime_t timeout;	/**< Time to wake/timeout setting. */
	/*@shared@*/
	osptr_t  lock_ptr;	/**< Pointer to shared resource that
				   this task is currently waiting on. */

	flag_t event_bits;	/**< If waiting for an event, this
				   indicates the bits that are being
				   waited on. */
#ifndef TIROS_REGISTER_PASSING
	/*@shared@*/
	osptr_t paramret_val;  /**< To pass return value. (For
				   architectures where passing
				   parameters through registers is
				   difficult */
#endif



#ifdef TIROS_STK_CHECK
	/*@shared@*/
	osstkptr_t  base_stk_ptr; 	/**< Only needed for
					   checking. */
	osword_t stksize;               /**< Used for checking */
#endif


};









#ifdef TIROSINT_DATA_DEBUG
/** \addtogroup os_advanced @{ */


/** Structure to capture TiROS internal data structures. */
typedef struct trintdata {
	tid_t    running_task;	    /**< ID of running task       */
	uint8_t  isr_nesting;       /**< Nesting level in ISR     */
	osword_t ctxt_switch_cnt;   /**< Count of contextswitches */
	struct TCB * tcblist;       /**< Pointer to array of TCBs */
} trintdata_t;



/** Get the internal data structures from TiROS. This can be used for
 *  debugging. 
 * @param [out] trdata  Pointer to structure where data should be
 * copied. NOTE: Not all data is copied.  See the definition of
 * trintdata_t */
void osint_gettrdata(trintdata_t * trdata);

/** Get the context swtich count */
osword_t osint_get_ctxt_switch_cnt(void);

/** @} */

#endif
























/* Default debug level is 0. There are 5 levels of debug.
 * 0 - No debugging.
 * 1 - Critical error messages only.
 * 2 - Adds Warning messages to 1.
 * 3 - Adds informational messages to 2.
 * 4 - Adds trace messages to 3. */
#ifndef TIROS_DEBUG_LEVEL
#define TIROS_DEBUG_LEVEL 0
#endif


/* Default macros do nothing */
#define TR_ASSERT(x, str, arg1) 
#define TR_ASSERTwTCB(x, str, arg1, arg2)
#define TR_MSG_CRIT(x)
#define TR_MSG_WARN(x)
#define TR_MSG_INFO(x)
#define TR_MSG_TRACE(x)
#define TR_MSG_TRACE_args(str, a, b)
#define TR_MSG_TRACE_wTCB(str, a, b)

#define TR_TIME_CRIT(x)
#define TR_TIME_WARN(x)
#define TR_TIME_INFO(x)


/* --------------------------------------------------  */
#if (TIROS_DEBUG_LEVEL > 0)   /* Critical Debugging Info */



#include <util.h>
void print_TCBarray(tid_t run_task, tid_t rdy_task, tid_t wt_task,
		    struct TCB* TCBarray,
		    tid_t * TCB_meta, tid_t *lklist_meta);


#undef TR_MSG_CRIT
#define TR_MSG_CRIT(x)  putstring("\nE:" x)



#undef TR_ASSERTwTCB
/* Assertion: Print Debugging information.
 * @param x Assertion condition.  Debugging info is printed only if x
 * is false.
 * @param str  Descriptive string that can be printed.
 * @param arg1 A numerical argument that can be printed
 * @param arg2 Full TCB info is printed if this parameter is non-zero */
#define TR_ASSERTwTCB(x, str, arg1, arg2)   		\
	if (!(x)) { 				\
    		putstring("\nE:" str); 		\
		puthexshort(__LINE__); 		\
		putstring(" arg: "); 		\
		puthexint((uint32_t)arg1, sizeof(arg1)); 		\
		putchar('\n'); 			\
		if (arg2)			\
			print_TCBarray( running_task(), \
				RDY_list_head(),       \
				WT_list_head(),       \
				TCBarray,             \
				rdywt_list_metadata,    \
				lock_list_metadata);   \
    	}


#undef TR_ASSERT
/* Assertion: Print Debugging information.
 * @param x Assertion condition.  Debugging info is printed only if x
 * is false.
 * @param str  Descriptive string that can be printed.
 * @param arg1 A numerical argument that can be printed */
#define TR_ASSERT(x, str, arg1)  \
	TR_ASSERTwTCB(x, str, arg1, 0)


#undef TR_TIME_CRIT
#define TR_TIME_CRIT(x) print_trtime(x)

#if (TIROS_DEBUG_LEVEL > 1)   /* Warning Debugging Info */
#undef TR_MSG_WARN
#define TR_MSG_WARN(x)  putstring("\nW:" x)

#undef TR_TIME_WARN
#define TR_TIME_WARN(x) print_trtime(x)


#if (TIROS_DEBUG_LEVEL > 2)  /* Informational Debugging */
#undef TR_MSG_INFO
#define TR_MSG_INFO(x) putstring("\nI:" x)


#undef TR_TIME_INFO
#define TR_TIME_INFO(x) print_trtime(x)

#if (TIROS_DEBUG_LEVEL > 3)  /* Trace Debugging */
#undef TR_MSG_TRACE
#define TR_MSG_TRACE(x)  putstring("\nT:" x)

#undef TR_MSG_TRACE_args
#define TR_MSG_TRACE_args(str,a,b) putchar(str); puthexchar(a); \
                         putchar('>');   puthexchar(b); putchar(' ')

#undef TR_MSG_TRACE_wTCB
#define TR_MSG_TRACE_wTCB(str, a, b) \
                        putstring("\n" str " "); puthexchar(a); \
                        putchar(' '); puthexchar(b); \
			print_TCBarray( running_task(), \
				RDY_list_head(),       \
				WT_list_head(),       \
				TCBarray,             \
				rdywt_list_metadata,    \
				lock_list_metadata);   


#endif /* TIROS_DEBUG_LEVEL > 3 -----------------------------*/
#endif /* TIROS_DEBUG_LEVEL > 2 -----------------------------*/
#endif /* TIROS_DEBUG_LEVEL > 1 -----------------------------*/
#endif /* TIROS_DEBUG_LEVEL > 0 -----------------------------*/










/* End Of File */
#endif  /* _TIROS_INTERNAL_H */

